package com.evil.plugin.es;

import org.elasticsearch.SpecialPermission;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptEngine;
import org.elasticsearch.script.ScriptException;
import org.elasticsearch.script.TemplateScript;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Map;
import java.util.Set;

/**
 * @author liyang
 * @date 2024-08-12 10:00
 */
public class RemoteScriptEngine implements ScriptEngine {
    private static final Logger logger = LoggerFactory.getLogger(RemoteScriptEngine.class);

    public static final String NAME = "formula";

    public RemoteScriptEngine() {
        SpecialPermission.check();
    }

    @Override
    public String getType() {
        return NAME;
    }

    @Override
    public <FactoryType> FactoryType compile(String name, String code, ScriptContext<FactoryType> context, Map<String, String> params) {
        logger.info("RemoteScriptEngine|compile|name:{}, code:{}, context:{}, param:{}", name, code, context, params);
        if (!context.instanceClazz.equals(TemplateScript.class)) {
            throw new IllegalArgumentException("remotex engine does not know how to handle context [" + context.name + "]");
        }

        try {
            TemplateScript.Factory compiled = RemoteExecutableScript::new;
            return context.factoryClazz.cast(compiled);
        } catch (Exception ex) {
            throw new ScriptException(ex.getMessage(), ex, Collections.emptyList(), code, NAME);
        }
    }

    @Override
    public Set<ScriptContext<?>> getSupportedContexts() {
        return Collections.singleton(TemplateScript.CONTEXT);
    }
}
